<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 基本结构
        function myPromise(executor) {
            let self = this;
            self.status = 'pending' //状态
            self.value = null; // 成功的结果
            self.reason = null; //失败的原因

            // 为了解决异步 存放的容器
            self.onFulFilledCallbacks = [];
            self.onRejectedCallbacks = [];

            function resolve(value) {
                // 状态判断
                if (self.status === 'pending') {
                    self.value = value; // 保存成功结果
                    self.status = 'fulfilled';
                    self.onFulFilledCallbacks.forEach(item => {
                        item(value)
                    });
                }
            }

            function reject(reason) {
                self.value = reason; // 失败的原因
                self.status = 'rejected';
                self.onRejectedCallbacks.forEach(item => {
                    item(reason)
                });
            }
            // 实例化之后，必须要立即执行一遍
            try {
                executor(resolve, reject)
            } catch (error) {
                reject(error)
            }
        }

        // .then()
        myPromise.prototype.then = function (onFulFilled, onRejected) {
            onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : function (data) {
                resolve(data)
            }
            onRejected = typeof onRejected === 'function' ? onRejected : function (err) {
                throw err
            }
            let self = this;
            if (self.status === 'pending') {
                self.onFulFilledCallbacks.push(onFulFilled);
                self.onRejectedCallbacks.push(onRejected);
            }
        }
        
        //promise.all手写实现
        function promiseAll(promiseArray) {
        	return new Promise((resolve, reject) => {
        		//如果传入的不是一个数组，就直接返回错误
        		if(!Array.isArray(promiseArray)) {
        			return reject(new Error("传入的参数不是一个数组！"))
        		}
        		const res = [];
        		const promiseNums = promiseArray.length;
        		/*
        		 * 对于传入的每一个promise对象，不确定其哪个先执行完毕，所以不能直接判断数组下标
        		 */
        		//由于js数组的特殊性，必须要这个计数
        		let counter = 0;
        		for(let i = 0;i < promiseNums;i++) {
        			Promise.resolve(promiseArray[i]).then(value => {
        				//执行完一个promise就将counter加1，直到所有的promise执行完毕
        				counter++;
        				//存储结果
        				res[i] = value;
        				if(counter === promiseNums) {
        					resolve(res);
        				}
        			}).catch(e => {
        				reject(e);
        			})
        		}
        	})
        }

        let demo1 = new myPromise((resolve, reject) => {
            // setTimeout(() => {
            //     resolve(123);
            // }, 3000)
            resolve(123);
        })
        demo1.then(data => console.log(data))
        
        let demo2 = promiseAll([6])
        demo2.then(res => {
        	console.log(res)
        })
    </script>
</body>

</html>